//
//  DataStore.m
//  ViewPoint
//
//  Created by Demiao Lin on 09-2-23.
//  Copyright 2009 Tsinghua. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"

#import "DataStore.h"

#import "NewSMTH.h"

#define kFilename	@"ViewPoint.sqlite3"

@implementation DataStore


-(void) putValue:(NSString*)value withKey:(NSString*) key {
	[self checkConnection];
    [db beginTransaction];
    [db executeUpdate:@"INSERT OR REPLACE INTO cache (cacheKey, cacheValue) VALUES (?, ?)",
            key,
            value];
    if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
    [db commit];
	[self close];
}

-(void) removeValueWithKey:(NSString*) key {
	[self checkConnection];
    [db beginTransaction];
    [db executeUpdate:@"DELETE FROM cache WHERE cacheKey=?", key];
	if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
    [db commit];
    [self close];
}

-(NSString*) getValueWithKey:(NSString*) key {
    NSString *value = nil;
	[self checkConnection];
    FMResultSet *rs = [db executeQuery:@"SELECT cacheValue FROM cache WHERE cacheKey=?", key];
    if ([rs next]) {
		value = [rs stringForColumn:@"cacheValue"];
    }
    [rs close];
	[self close];
    return value;
}

-(Board*) getBoardWithName:(NSString*)board_name {
    Board *board=nil;
	[self checkConnection];
    FMResultSet *rs = [db executeQuery:@"SELECT bid, bname, desc FROM boards WHERE lower(bname)=?", [board_name lowercaseString]];
    if ([rs next]) {
        int bid = [rs intForColumn:@"bid"];
        NSString *bname = [rs stringForColumn:@"bname"];
        NSString *desc = [rs stringForColumn:@"desc"];
        
        //NSLog(@"Board From SQLite: %d %@ %@", bid, bname, desc);
        
        int order = 1;
		board = [[Board alloc] initWithName:bname bid:(NSInteger*)bid order:(NSInteger*)order desc:desc];
    }
    [rs close];
	[self close];
    return board;
}

-(void) addBoard:(Board*)board {
    if(board){
        [self addBoard:board.bname bid:board.bid desc:board.desc];
	}
}

-(void) addBoard:(NSString*)board_name bid:(NSInteger*)board_id desc:(NSString*)description{
    [self checkConnection];
	[db beginTransaction];
    [db executeUpdate:@"INSERT OR IGNORE INTO boards (bid, bname, desc) VALUES (?, ?, ?)" ,
            [NSNumber numberWithInteger:(NSInteger)board_id],
            board_name,
            description];
    if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
    [db commit];
	[self close];
}

-(NSMutableArray*) getFavouriteBoards {
	[self checkConnection];
    NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:20] autorelease];
    
    FMResultSet *rs = [db executeQuery:@"SELECT bid, bname, desc, sequenceNum FROM favourite_boards ORDER BY sequenceNum ASC"];
    while ([rs next]) {
        /*
		NSLog(@"Board: %d %@ %@ %d",
              [rs intForColumn:@"bid"],
              [rs stringForColumn:@"bname"],
              [rs stringForColumn:@"desc"],
              [rs intForColumn:@"sequenceNum"]);
		*/
		Board *board = [[[Board alloc] initWithName:[rs stringForColumn:@"bname"] bid:(NSInteger*)[rs intForColumn:@"bid"] order:(NSInteger*)[rs intForColumn:@"sequenceNum"] desc:[rs stringForColumn:@"desc"]] autorelease];
        [array addObject:board];
    }
    [rs close];
	[self close];
    return array;
}

-(void) saveFavouriteBoards:(NSMutableArray*)boards {
	[self checkConnection];
    
    [db beginTransaction];
	[db executeUpdate:@"DELETE FROM favourite_boards"];
	if ([db hadError]) {
		NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
	}
    int i=1;
    for(Board *board in boards){
		NSLog(@"save board: %@", board.bname);
        [db executeUpdate:@"INSERT OR REPLACE INTO favourite_boards (bid, bname, desc, sequenceNum) VALUES (?, ?, ?, ?)" ,
                [NSNumber numberWithInteger:(NSInteger)board.bid],
                board.bname,
                board.desc,
                [NSNumber numberWithInt:i]];
        if ([db hadError]) {
            NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
        }
        i++;
    }
    [db commit];
	[self close];
}

- (NSString *)dataFilePath {
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	return [documentsDirectory stringByAppendingPathComponent:kFilename];
}

-(id) init{
	if( (self=[super init]) != nil ){
		[self initialize];
	}
	return self;
}

-(void) checkConnection {
    if(db!=nil && [db goodConnection]){
        
    } else {
        [self open];
    }
}

-(void) open {
	db = [FMDatabase databaseWithPath:[self dataFilePath]];
    if (![db open]) {
        NSLog(@"Could not open db.");
    }
    
    [db setShouldCacheStatements:YES];
}

-(void) close{
	[db close];
    db = nil;
}

-(void) initialize {
    [self checkConnection];
    
    [db executeUpdate:@"CREATE TABLE IF NOT EXISTS boards ( bid INTEGER PRIMARY KEY, bname TEXT UNIQUE, desc TEXT );"];
    if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
    
    [db executeUpdate:@"CREATE TABLE IF NOT EXISTS favourite_boards ( bid INTEGER PRIMARY KEY, bname TEXT UNIQUE, desc TEXT, sequenceNum INTEGER DEFAULT 0 );"];
    if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
    
    [db executeUpdate:@"CREATE TABLE IF NOT EXISTS cache ( id INTEGER PRIMARY KEY, cacheKey TEXT UNIQUE, cacheValue TEXT );"];
    if ([db hadError]) {
        NSLog(@"DB Err %d: %@", [db lastErrorCode], [db lastErrorMessage]);
    }
	
	[self close];
}

- (void)dealloc {
    [super dealloc];
}

@end
